package com.atguigu.exam.service.impl;

import com.atguigu.exam.entity.AnswerRecord;
import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.AnswerRecordMapper;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.*;
import com.atguigu.exam.vo.ExamRankingVO;
import com.atguigu.exam.vo.GradingResult;
import com.atguigu.exam.vo.StartExamVo;
import com.atguigu.exam.vo.SubmitAnswerVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 考试记录Service实现类
 * 实现考试记录相关的业务逻辑
 */
@Transactional
@Service
public class ExamRecordServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamRecordService {

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private PaperService paperService;

    @Autowired
    private AnswerRecordService answerRecordService;

    @Autowired
    private AnswerRecordMapper answerRecordMapper;

    @Autowired
    private AIService aiService;

    @Override
    public ExamRecord startExam(StartExamVo startExamVo) {
        //判断是否考试记录,根据试卷id,考试学生姓名,status卡松hi状态进行查询
        ExamRecord examRecord = examRecordMapper.selectOne(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, startExamVo.getPaperId()).eq(ExamRecord::getStudentName, startExamVo.getStudentName()).eq(ExamRecord::getStatus, "进行中"));
        //判断ExamRecord是否为空
        if (examRecord != null) {
            return examRecord;
        }
        //创建ExamRecord对象
        examRecord = new ExamRecord();
        //为ExamRecord设置paperId
        examRecord.setExamId(startExamVo.getPaperId());
        //为ExamRecord设置studentName
        examRecord.setStudentName(startExamVo.getStudentName());
        //设置开始时间
        examRecord.setStartTime(LocalDateTime.now());
        //设置考试状态
        examRecord.setStatus("进行中");
        //设置切屏次数
        examRecord.setWindowSwitches(0);
        //调用baseMapper中的insert进行插入考试记录
        baseMapper.insert(examRecord);
        return examRecord;
    }

    @Override
    public ExamRecord getExamRecordById(Integer id) {
        //根据id获取考试记录
        ExamRecord examRecord = baseMapper.selectById(id);
        //获取考试记录中的试卷详情
        Paper paper = paperService.getDetailById(examRecord.getExamId());
        //获取所有的题目(没有选项和答案)
        List<Question> questions = paper.getQuestions();
        /*//给题目填充选项和答案
        questions.forEach(question -> {
            //获取所有的选项和答案
            Question questionContainsChoiceAndAnswer = questionMapper.getQuestionDetailsById(question.getId());
            //设置选项和答案
            question.setChoices(questionContainsChoiceAndAnswer.getChoices());
            question.setAnswer(questionContainsChoiceAndAnswer.getAnswer());
        });*/
        questionService.fillAnswerAndChoices(questions);
        //将题目顺序进行排序
        questions.sort((o1, o2) -> o1.getType().compareTo(o2.getType()));
        //设置paper
        examRecord.setPaper(paper);
        //获取考试记录的答题记录列表（供判卷和前端展示使用）
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));
        if (!CollectionUtils.isEmpty(answerRecords)) {
            //设置答题记录
            examRecord.setAnswerRecords(answerRecords);
        }
        return examRecord;
    }

    @Override
    public void submitAnswers(Integer examRecordId, List<SubmitAnswerVo> answers) {
        //根据id获取考试记录
        ExamRecord examRecord = baseMapper.selectById(examRecordId);
        //给examRecord的结束时间赋值
        examRecord.setEndTime(LocalDateTime.now());
        //给examRecord的status设置成已完成
        examRecord.setStatus("已完成");
        //调用根据id更新的方法
        baseMapper.updateById(examRecord);
        //给答案进行赋值,先进行转换List<SubmitAnswerVo> answers转成List<AnswerRecord> answers
        List<AnswerRecord> answerRecordList = answers.stream().map(answer -> {
            AnswerRecord answerRecord = new AnswerRecord(examRecordId, answer.getQuestionId(), answer.getUserAnswer());
            return answerRecord;
        }).collect(Collectors.toList());
        //进行批量添加
        answerRecordService.saveBatch(answerRecordList);

        //调用判卷的方法
        gradePaper(examRecordId);
    }

    @Override
    public void deleteExamRecordById(Integer id) {
        //判断处于进行中的试卷记录不能删除
        //根据id查询考试记录
        ExamRecord examRecord = baseMapper.selectById(id);
        if ("进行中".equals(examRecord.getStatus())) {
            throw new ExamException(1008, "进行中的考试记录不能删除");
        }
        //删除考试记录
        baseMapper.deleteById(id);
        //删除答案记录表
        answerRecordMapper.delete(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));
    }

    @Override
    public List<ExamRankingVO> getExamRanking(Integer paperId, Integer limit) {
        return baseMapper.getExamRanking(paperId, limit);
    }

    private void gradePaper(Integer examRecordId) {
        //根据examRecordId获取考试详情
        ExamRecord examRecord = getExamRecordById(examRecordId);
        //获取答案记录
        List<AnswerRecord> answerRecords = examRecord.getAnswerRecords();
        //获取所有的题目
        List<Question> questions = examRecord.getPaper().getQuestions();
        //将questions转成map,以questionId为key 以question为value
        Map<Long, Question> questionMap = questions.stream().collect(Collectors.toMap(Question::getId, q -> q));
        //遍历所有答案记录
        answerRecords.forEach(answerRecord -> {
            //获取答案记录中的题目id
            Long questionId = answerRecord.getQuestionId();
            //根据questionId获取对应的题目
            Question question = questionMap.get(questionId);
            //判断是不是判断题,需要将答案记录表中的T或者F转换为TRUE或者FALSE
            if ("JUDGE".equals(question.getType())) {
                answerRecord.setUserAnswer(answerRecord.getUserAnswer().equalsIgnoreCase("T") ? "TRUE" : "FALSE");
            }
            //获取用户输入的答案
            String userAnswer = answerRecord.getUserAnswer();
            //获取正确答案
            String correctAnswer = question.getAnswer().getAnswer();
            //判断是不是简答题TEXT
            if ("TEXT".equalsIgnoreCase(question.getType())) {
                //进行答案比对
                if (correctAnswer.equalsIgnoreCase(userAnswer)) {
                    //表示是正确答案,加分,设置为正确
                    answerRecord.setScore(question.getPaperScore().intValue());
                    answerRecord.setIsCorrect(1);
                } else {
                    //表示不是正确答案,不加分,设置为不正确
                    answerRecord.setScore(0);
                    answerRecord.setIsCorrect(0);
                }
            }
            //调用AI处理简答题
            GradingResult gradingResult = aiService.gradeTextQuestion(question, userAnswer);
            //给简答题设置分数
            answerRecord.setScore(gradingResult.getScore());
            //判断ai设置的分数在那个分数段,0分表示全错,1分表示全对,2分表示部分正确
            if (gradingResult.getScore() == question.getPaperScore().intValue()) {
                //表示全对,将isCorrect设置为1
                answerRecord.setIsCorrect(1);
                //设置ai反馈
                answerRecord.setAiCorrection(gradingResult.getFeedback());
            } else if (gradingResult.getScore() == 0) {
                //表示全错,将isCorrect设置为0
                answerRecord.setIsCorrect(0);
                //设置ai给出的原因
                answerRecord.setAiCorrection(gradingResult.getReason());
            } else {
                //表示部分正确,将isCorrect设置为2
                answerRecord.setIsCorrect(2);
                //设置ai给出的原因
                answerRecord.setAiCorrection(gradingResult.getReason());
            }
            //更新answerRecord
            answerRecordMapper.updateById(answerRecord);
        });

        //获取总分
        Integer totalScore = answerRecords.stream().mapToInt(AnswerRecord::getScore).sum();
        //计算总的正确的题目数量
        Integer totalCorrectCount = answerRecords.stream().filter(answerRecord -> answerRecord.getIsCorrect() == 1).mapToInt(answerRecord -> 1).sum();
        //将总分记录到考试记录中
        examRecord.setScore(totalScore);
        //调用AI获取评语
        String summary = aiService.getSummary(totalScore, examRecord.getPaper().getTotalScore().intValue(), examRecord.getPaper().getQuestionCount(), totalCorrectCount);
        //给examRecord设置answer评语
        examRecord.setAnswers(summary);
        //将考试状态设置为已批阅
        examRecord.setStatus("已批阅");
        //更新考试记录表
        baseMapper.updateById(examRecord);
    }
}